package com.audaque.jadmin.common.action;

import java.beans.PropertyEditorSupport;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.security.Principal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.NativeWebRequest;

import com.audaque.jadmin.common.model.Constants;
import com.audaque.jadmin.common.model.MessageModel;
import com.audaque.jadmin.common.utils.CookieUtil;
import com.audaque.jadmin.system.model.User;
import com.audaque.jadmin.system.shiro.UserRealm.ShiroUser;

/**
 * @Description :
 * @FileName: BaseAction.java
 * @Author :WeiHui.Zhang
 * @Data : 2015年9月23日 上午8:51:17
 * @Version:V1.00
 */
public abstract class BaseAction {

	/**
	 * 一般来说，inline会在浏览器里面尝试打开要下载的文件，也要看你下载的文件格式，如果是word，pdf等格式可以在浏览器里面打开的文件，
	 * 浏览器会直接打开。
	 */
	public static final String CONTENT_DISPOSITION_INLINE = "inline";
	/**
	 * 而对于attachment的话，浏览器会让你下载这个文件。
	 * 当然对于zip等这种在浏览器里面不能直接打开的文件，inline跟attachment的处理方式一样，也会让你下载这个文件。
	 */
	public static final String CONTENT_DISPOSITION_ATTACHMENT = "attachment";

	protected static final Logger LOG = LoggerFactory.getLogger(BaseAction.class);

	@InitBinder
	public void initBinder(WebDataBinder dataBinder) {
		// binder.registerCustomEditor(String.class, new EscapeHtmlEditor());
		// dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new
		// SimpleDateFormat("yyyy-MM-dd"), true));
		dataBinder.registerCustomEditor(boolean.class, new CustomBooleanEditor(null, null, true));

		dataBinder.registerCustomEditor(String.class, new PropertyEditorSupport() {

			public void setAsText(String value) {
				try {
					if (value != null) {
						setValue(value.trim());
					} else {
						setValue(null);
					}
				} catch (Exception e) {
					setValue(null);
				}
			}
		});
		dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() {

			public void setAsText(String value) {
				try {
					if (StringUtils.isNotBlank(value) && value.contains(":")) {
						setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value));
					} else if (StringUtils.isNotBlank(value)) {
						setValue(new SimpleDateFormat("yyyy-MM-dd").parse(value));
					} else {
						setValue(null);
					}
				} catch (ParseException e) {
					setValue(null);
				}
			}
		});
	}

	protected abstract String getJspPathPrefix();

	protected String getJspPathPrefix(String path) {
		return getJspPathPrefix() + path;
	}

	protected ResponseEntity<byte[]> loadImage(File img) throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		headers.setContentDispositionFormData(CONTENT_DISPOSITION_INLINE,
				new String(img.getName().getBytes("GBK"), "ISO-8859-1"));
		return new org.springframework.http.ResponseEntity<byte[]>(FileUtils.readFileToByteArray(img), headers,
				HttpStatus.OK);
	}

	protected ResponseEntity<byte[]> loadFile(File file) throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		headers.setContentDispositionFormData(CONTENT_DISPOSITION_ATTACHMENT, file.getName());
		return new org.springframework.http.ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers,
				HttpStatus.OK);
	}

	protected void download(File file, HttpServletResponse response) throws IOException {
		response.reset();
		response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName());
		response.addHeader(HttpHeaders.CONTENT_LENGTH, "" + file.length());
		// response.setContentType("application/octet-stream;charset=UTF-8");
		response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + ";charset=UTF-8");
		OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
		outputStream.write(FileUtils.readFileToByteArray(file));
		outputStream.flush();
		outputStream.close();
	}

	/**
	 * 取当前登录用户名
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	protected String getUserName(HttpServletRequest request) {
		return CookieUtil.getCookie(request, Constants.CURRENT_USER_NAME);
	}

	/**
	 * 取当前登录用户类型
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	protected String getUserType(HttpServletRequest request) {
		return CookieUtil.getCookie(request, Constants.CURRENT_USER_TYPE);
	}

	/**
	 * 取当前登录用户
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	protected User getCurrentUser(HttpServletRequest request) {
		return (User) request.getAttribute(Constants.CURRENT_USER);
	}

	/**
	 * 获取当前用户对象shiro
	 * 
	 * @return
	 */
	public ShiroUser getCurrentShiroUser() {
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		return user;
	}

	/**
	 * 获取当前用户session
	 * 
	 * @return session
	 */
	public static Session getSession() {
		Session session = SecurityUtils.getSubject().getSession();
		return session;
	}

	/**
	 * 获取当前用户对象
	 * 
	 * @return user
	 */
	public static User getCurrentUser() {
		Session session = SecurityUtils.getSubject().getSession();
		if (null != session) {
			return (User) session.getAttribute("user");
		} else {
			return null;
		}
	}

	/**
	 * 取得当前用户ID
	 * 
	 * @param request
	 * @return
	 */
	protected Integer getCurrentUserId(HttpServletRequest request) {
		return getCurrentUser(request).getUserId();
	}

	// 清楚Cookies
	protected void clearCookie(HttpServletRequest request, HttpServletResponse response, String... cookieKeys) {
		List<String> key_list = Arrays.asList(cookieKeys);
		CookieUtil.clearCookie(request, response, key_list);
	}

	// @ExceptionHandler({ UnauthorizedException.class })
	// @ResponseStatus(HttpStatus.UNAUTHORIZED)
	// public ModelAndView processUnauthenticatedException(NativeWebRequest
	// request, UnauthorizedException e) {
	// Principal userPrincipal = request.getUserPrincipal();
	// System.out.println(userPrincipal.getName());
	// ModelAndView mv = new ModelAndView();
	// mv.addObject("exception", e);
	// mv.setViewName("unauthorized");
	// return mv;
	// }

	@ExceptionHandler({ UnauthorizedException.class })
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	@ResponseBody
	public MessageModel processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
		Principal userPrincipal = request.getUserPrincipal();
		System.out.println(userPrincipal.getName());
		return new MessageModel(false, "没有权限");
	}
}
